#ifndef __EVENTLOOP_H__
#define __EVENTLOOP_H__

#include "TcpConnection.hpp"
#include "MutexLock.hpp"
#include <sys/epoll.h>

#include <vector>
#include <map>
#include <memory>

using std::vector;
using std::map;
using std::shared_ptr;

namespace wd
{

class TcpConnection;

using TcpConnectionPtr = shared_ptr<TcpConnection>;

using TcpConnectionCallback = function<void(TcpConnectionPtr)>;

using Functor = function<void()>;

class Acceptor; // 类的前向声明，不需要头文件

class EventLoop
{
public:
    EventLoop(Acceptor &);
    
    ~EventLoop();
    
    void loop();
    
    void unloop(); // 退出循环，要与 loop 函数运行在不同的线程
    
    void runInLoop(Functor && cb);
    
    void setAllCallbacks(
                         TcpConnectionCallback && cb1 , 
                         TcpConnectionCallback && cb2 , 
                         TcpConnectionCallback && cb3
                        )
    {
        // 表达完整的移动语义，需要使用 std::move
        // 将左值 (cb1 , cb2 , cb3) 转换成右值
        // std::move 的作用是显式将一个左值转换成右值
        _onConnection = std::move(cb1);
        _onMessage    = std::move(cb2);
        _onClose      = std::move(cb3);
    }

private:
    void waitEpollFd();
    
    void handleNewConnection();
    
    void handleMessage(int);

    int  createEpollFd();
    
    void addEpollReadEvent(int);
    
    void delEpollReadEvent(int);

    int  createEventfd();
    
    void handleReadEvent();
    
    void wakeup();
    
    void doPendingFunctors();

private:
    int                         _epfd;
    int                         _eventfd;
    bool                        _isLooping;
    Acceptor &                  _acceptor;
    vector<struct epoll_event>  _evtArr;
    map<int , TcpConnectionPtr> _conns;
    TcpConnectionCallback       _onConnection;
    TcpConnectionCallback       _onMessage;
    TcpConnectionCallback       _onClose;
    vector<Functor>             _pendingFunctors;
    MutexLock                   _mutex;
};

} // end of namespace wd



#endif

